package com.wlyuan.open.scanner.repository.impl;

import com.wlyuan.open.constants.CustomerTypeEnum;
import com.wlyuan.open.scanner.application.factory.SyncFactory;
import com.wlyuan.open.scanner.assembler.ScannerCustomerAssembler;
import com.wlyuan.open.scanner.config.GroupProperties;
import com.wlyuan.open.scanner.constant.AddressTypeEnum;
import com.wlyuan.open.scanner.constant.Constants;
import com.wlyuan.open.scanner.dao.entity.CustomerDO;
import com.wlyuan.open.scanner.dao.mapper.CustomerMapper;
import com.wlyuan.open.scanner.domain.customer.Customer;
import com.wlyuan.open.scanner.domain.customer.CustomerConvert;
import com.wlyuan.open.scanner.repository.AddressRepository;
import com.wlyuan.open.scanner.repository.CompanyRepository;
import com.wlyuan.open.scanner.repository.CustomerConfigRepository;
import com.wlyuan.open.scanner.repository.CustomerRepository;
import com.wlyuan.open.scanner.utils.StreamUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import lombok.var;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * @author lijing
 * @description
 */
@Service
@Slf4j
@RequiredArgsConstructor
public class CustomerRepositoryImpl implements CustomerRepository {
    private final CustomerMapper customerMapper;
    private final AddressRepository addressRepository;
    private final SyncFactory syncFactory;
    private final GroupProperties groupProperties;
    private final CompanyRepository companyRepository;
    private final CustomerConfigRepository customerConfigRepository;

    @Override
    public List<Customer> list() {
        logger.info("所属公司id > 0");
        List<CustomerDO> list = customerMapper.list();
        if (CollectionUtils.isEmpty(list)) {
            return Collections.emptyList();
        }
        logger.info("老数据数据量，size：{}", list.size());
        //处理自己类型
        process(list);
        //获取地址发货方地址
        logger.info("根据客户id获取发货放地址信息");
        var customerIds = StreamUtils.mapList(list, CustomerDO::getCustomerId);
        var addressMap = addressRepository.getAddressMap(customerIds, AddressTypeEnum.CUSTOMER.getValue());
        //发货地址
        list.forEach(data -> data.setAddressList(addressMap.get(data.getCustomerId())));
        return CustomerConvert.convert(list);

    }

    private void process(List<CustomerDO> list) {
        var cIds = Constants.CUSTOMER_NAME.keySet().stream().collect(Collectors.toList());
        list.forEach(data -> {
            //处理自己类型
            boolean self = data.getCustomerOwnercompany().equals(data.getCustomerCompanyid()) && CustomerTypeEnum.isOnline(data.getCustomerUnderline());
            if (self) {
                if (StringUtils.isBlank(data.getCustomerName())) {
                    Optional.ofNullable(companyRepository.getCompanyTenantById(data.getCustomerOwnercompany())).ifPresent(c -> {
                        data.setCustomerName(StringUtils.isNotBlank(c.getName()) ? c.getName() : "#".concat(String.valueOf(c.getTenantId())));
                    });
                }
                data.setCustomerUnderline(CustomerTypeEnum.MYSELF.getValue());
            }

            if (cIds.contains(data.getCustomerId())) {
                data.setCustomerName(Constants.CUSTOMER_NAME.get(data.getCustomerId()));
            }

            if (groupProperties.groupTenantList().contains(data.getCustomerOwnercompany())) {
                data.setCustomerUpdater(0L);
                data.setCustomerCreator(0L);
            }

            data.setCustomerConfig(customerConfigRepository.getByCustomerId(data.getCustomerId(), data.getCustomerOwnercompany()));
        });
    }

    @Override
    public Customer getById(Long customerId) {
        return Optional.ofNullable(customerId).map(id -> {
            var data = customerMapper.getById(id);

            return Optional.ofNullable(data).map(customer -> {
                process(Arrays.asList(customer));
                var addressMap = addressRepository.getAddress(id, AddressTypeEnum.CUSTOMER.getValue());
                customer.setAddressList(addressMap.get(customer.getCustomerId()));
                return CustomerConvert.convert(customer);
            }).orElse(null);

        }).orElse(null);
    }

    @Override
    public List<Long> getByTime(String startTime, String endTime) {
        return customerMapper.getByTime(startTime, endTime);
    }

    @Override
    public List<Long> getByTenantIdTime(Long tenantId, String startTime, String endTime) {
        return customerMapper.getByTenantIdTime(tenantId, startTime, endTime);
    }

    @Override
    public Customer getCustomerById(Long customerId) {
        return Optional.ofNullable(customerId).map(id -> {
            var data = customerMapper.getById(id);
            return Optional.ofNullable(data).map(customer -> {
                process(Arrays.asList(customer));
                return CustomerConvert.convert(customer);
            }).orElse(null);

        }).orElse(null);
    }

    @Override
    public Customer getByCompanyId(Long ownerCompanyId, Long companyId) {
        var data = customerMapper.getByCompanyId(ownerCompanyId, companyId);
        return Optional.ofNullable(data).map(customer -> {
            process(Arrays.asList(customer));
            return CustomerConvert.convert(customer);
        }).orElse(null);
    }

    @Override
    public void getByTenantId(Long tenantId) {
        Optional.ofNullable(tenantId).ifPresent(tenant -> {
            //集团试用，线下的，后面要去掉
            var list = customerMapper.getByTenantId(tenant);
            if (CollectionUtils.isEmpty(list)) {
                logger.info("根据租户{}查询客户数据为0", tenant);
                return;
            }
            logger.info("根据租户{}查询客户数据为{}", tenant, list.size());
            list.forEach(customer -> {
                process(Arrays.asList(customer));
                var addressMap = addressRepository.getAddress(customer.getCustomerId(), AddressTypeEnum.CUSTOMER.getValue());
                customer.setAddressList(addressMap.get(customer.getCustomerId()));
                var data = CustomerConvert.convert(customer);
                syncFactory.sync(ScannerCustomerAssembler.assemble(data));
            });
        });
    }
}
